import pandas as pd
import numpy as np
from datetime import datetime


def load_and_preprocess_data():
    """加载并预处理基础数据"""
    # 加载数据并指定学生ID为字符串类型
    grade_data = pd.read_csv("data/5_chengji.csv", dtype={'mes_StudentID': str})

    # 处理异常分数和日期
    grade_data = grade_data[~grade_data['mes_Score'].isin([-1, -2, -3])]
    grade_data['exam_sdate'] = pd.to_datetime(grade_data['exam_sdate'])

    # 排除不需要的学科
    return grade_data[grade_data['mes_sub_name'] != '1B模块总分']


def analyze_student(student_id, alpha=0.3):
    """
    分析指定学生的成绩
    :param student_id: 需要分析的学生ID（字符串或数字）
    :param alpha: 平滑系数（0-1）
    :return: 该学生的预测数据字典
    """
    # 加载预处理数据
    grade_data = load_and_preprocess_data()

    # 筛选指定学生
    student_id = str(student_id)
    student_data = grade_data[grade_data['mes_StudentID'] == student_id]

    if student_data.empty:
        return {"error": f"未找到学生 {student_id} 的记录"}

    # 按学科分组分析
    grouped = student_data.groupby('mes_sub_name')
    result = {}

    # 初始化总分相关变量
    total_score = 0.0
    valid_subjects = 0

    for subject, group in grouped:
        # 按考试时间排序
        sorted_group = group.sort_values('exam_sdate', ascending=True)
        valid_scores = sorted_group[['exam_sdate', 'mes_Score']]

        # 构建历史记录（显示最近10次）
        history = [{
            "时间": row['exam_sdate'].strftime("%Y-%m-%d"),
            "成绩": row['mes_Score']
        } for _, row in valid_scores.tail(10).iterrows()]

        # 计算预测指标
        scores = valid_scores['mes_Score'].tolist()
        if scores:
            # 指数平滑预测
            smoothed = scores[0]
            for score in scores[1:]:
                smoothed = alpha * score + (1 - alpha) * smoothed

            # 计算统计量
            predicted = round(smoothed, 2)
            average_all = round(np.mean(scores), 2)
            trend = analyze_trend(scores)

            # 累加总分
            if predicted is not None:
                total_score += predicted
                valid_subjects += 1
        else:
            predicted = average_all = trend = None

        result[subject] = {
            "历史成绩": history,
            "预测成绩": predicted,
            "平均分": average_all,
            "成绩趋势": trend
        }

    # 添加总分信息
    if valid_subjects > 0:
        avg_total = round(total_score / valid_subjects, 2)
    else:
        avg_total = 0.0

    result['总分'] = {
        '预测总分': round(total_score, 2),
        '平均总分': avg_total,
        '参与科目数': valid_subjects
    }

    return result


def analyze_trend(scores):
    """分析成绩趋势"""
    if len(scores) < 2:
        return "数据不足"

    recent = scores[-3:] if len(scores) >= 3 else scores
    diffs = np.diff(recent)

    if all(d > 0 for d in diffs):
        return "上升趋势"
    elif all(d < 0 for d in diffs):
        return "下降趋势"
    else:
        return "波动趋势"